package mini.util;

import java.util.Map;

/**
 * Utilities
 * 
 * @author Meyer
 */
public class MiniUtil {

	/**
	 * See what's in the environment
	 * @param env - Map 
	 * @return Stirng, labeled key/value pairs
	 */
	public static String printEnvironment(Map<String,Integer> env) {
		StringBuilder sb = new StringBuilder();
		for(Map.Entry<String, Integer> entrySet: env.entrySet()) {
			sb.append(" [key: ");
			sb.append(entrySet.getKey());
			sb.append(" value: ");
			sb.append((entrySet.getValue() != null ? entrySet.getValue() : "null"));
			sb.append("] ");
		}
		return sb.toString();
	}
	
	/**
	 * Strip comments off the end of a line
	 * 
	 * This:
	 * LDA temp1  ; load something
	 * Gets returned as:
	 * LDA temp1
	 * 
	 * And this:
	 * LDA temp1
	 * Gets returned as 
	 * LDA temp1
	 * 
	 * @param line Some line of code
	 * @return The line without comments
	 */
	public static String removeAnyComments(String line) {
		int commentAt = line.indexOf(";");
		if( commentAt != -1 ) {
			return line.substring(0,commentAt);
		}
		return line;
	}

	/**
	 * This takes a line with a symbolic location marker and
	 * strips it. For example, if the line is:
	 * 
	 * L1: LDA T1
	 * 
	 * It would return:
	 * 
	 * LDA T1
	 * 
	 * If the line is:
	 * 
	 * L1: l2: LDA t1
	 * 
	 * It would return
	 * 
	 * LDA t1
	 * 
	 * @param line
	 * @return
	 */
	public static String removeAnyLocationMarkers(String line) {
		
		if( line != null ) {
			int colonIndex = line.lastIndexOf(":");
			
			if( colonIndex != -1 && colonIndex < (line.length()-1)) {
				return line.substring(colonIndex+1);
			}
		}
		
		return line;
	}

	/**
	 * A line is a comment if it begins with a semicolon, or
	 * if it is blank
	 * 
	 * @param line Line to check
	 * @return True if it is a comment
	 */
	public static boolean isComment(String line) {
		if( line == null ) {
			return true;
		}
		if( line.trim().length() == 0 ) {
			return true;
		}
		if( line.charAt(0) == ';' ) {
			return true;
		}
		
		return false;
	}

	/**
	 * Given a line of code, return an index of location markers.
	 * 
	 * Something like this:
	 * 
	 * L1: LDA 1
	 *
	 * Returns a single marker of L1
	 * 
	 * Something like this:
	 * 
	 * L1: L2: LDA 1
	 * 
	 * Returns two markers of L1 and L2
	 * 
	 * @param line
	 * @return The list of markers or null if there are none
	 */
	public static String[] getMarkersFromLine(String line ) {
		int markersEndAt = line.lastIndexOf(":");
		String[] markers = null;
		if( markersEndAt != -1 ) {
			String markersString = line.substring(0,markersEndAt);
			markers = markersString.split(" ");
			// Make sure the markers don't end with a :
			for( int i = 0; i < markers.length; i++ ) {
				if( markers[i].endsWith(":") ) {
					markers[i] = markers[i].substring(0,markers[i].length()-1);
				}
			}
		}
		return markers;
	}
	
	/**
	 * Reports an error in the parsing at either the optimize, rewrite, or linking phase
	 * This will write messages to System.err.
	 * 
	 * @param lineNumber An absolute line number (including comments and blanks) for reporting he error
	 * @param line The line that had the problem
	 * @param phase What phase we were in (linking, optimizing, rewriting)
	 */
	public static void reportParseError( int lineNumber, String line, String phase ) {
		System.err.println( "Malformed statement in line " + lineNumber + " of symbolic code; terminating " + phase + "." );
		System.err.println( "Statement was: " + line );
		System.err.println( "Attempting to continue but this means there will be errors in the output" );
	}


}
